using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;
using TaskStatus = SumerCoreDevOps.Shared.Enums.TaskStatus;

namespace SumerCoreDevOps.Infrastructure.Workflow;

/// <summary>
/// 工作流实例追踪器
/// </summary>
public class WorkflowInstanceTracker
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly ILogger<WorkflowInstanceTracker> _logger;
    private readonly ConcurrentDictionary<long, PipelineInstance> _runningInstances = new();

    public WorkflowInstanceTracker(FreeSQLProvider dbProvider, ILogger<WorkflowInstanceTracker> logger)
    {
        _dbProvider = dbProvider;
        _logger = logger;
    }

    /// <summary>
    /// 创建流水线实例
    /// </summary>
    public async Task<PipelineInstance> CreateInstanceAsync(
        long pipelineId,
        int buildNumber,
        string? commitHash,
        string? commitMessage,
        string? triggeredBy)
    {
        var instance = new PipelineInstance
        {
            PipelineId = pipelineId,
            BuildNumber = buildNumber,
            Status = TaskStatus.Pending,
            CommitHash = commitHash,
            CommitMessage = commitMessage,
            TriggeredBy = triggeredBy
        };

        instance.Id = (long)await _dbProvider.Orm.Insert(instance).ExecuteIdentityAsync();

        _runningInstances.TryAdd(instance.Id, instance);

        _logger.LogInformation("创建流水线实例: PipelineId={PipelineId}, BuildNumber={BuildNumber}, InstanceId={InstanceId}",
            pipelineId, buildNumber, instance.Id);

        return instance;
    }

    /// <summary>
    /// 启动实例
    /// </summary>
    public async Task StartInstanceAsync(long instanceId)
    {
        await _dbProvider.Orm.Update<PipelineInstance>()
            .Set(i => i.Status, TaskStatus.Running)
            .Set(i => i.StartTime, DateTime.UtcNow)
            .Where(i => i.Id == instanceId)
            .ExecuteAffrowsAsync();

        if (_runningInstances.TryGetValue(instanceId, out var instance))
        {
            instance.Status = TaskStatus.Running;
            instance.StartTime = DateTime.UtcNow;
        }

        _logger.LogInformation("启动流水线实例: {InstanceId}", instanceId);
    }

    /// <summary>
    /// 完成实例
    /// </summary>
    public async Task CompleteInstanceAsync(long instanceId, TaskStatus finalStatus)
    {
        await _dbProvider.Orm.Update<PipelineInstance>()
            .Set(i => i.Status, finalStatus)
            .Set(i => i.EndTime, DateTime.UtcNow)
            .Where(i => i.Id == instanceId)
            .ExecuteAffrowsAsync();

        if (_runningInstances.TryRemove(instanceId, out var instance))
        {
            instance.Status = finalStatus;
            instance.EndTime = DateTime.UtcNow;
        }

        _logger.LogInformation("完成流水线实例: {InstanceId}, 状态: {Status}", instanceId, finalStatus);
    }

    /// <summary>
    /// 取消实例
    /// </summary>
    public async Task CancelInstanceAsync(long instanceId)
    {
        await CompleteInstanceAsync(instanceId, TaskStatus.Cancelled);
        _logger.LogInformation("取消流水线实例: {InstanceId}", instanceId);
    }

    /// <summary>
    /// 获取实例详情
    /// </summary>
    public async Task<PipelineInstance?> GetInstanceAsync(long instanceId)
    {
        return await _dbProvider.Orm.Select<PipelineInstance>()
            .Where(i => i.Id == instanceId)
            .IncludeMany(i => i.Tasks)
            .Include(i => i.Pipeline)
            .FirstAsync();
    }

    /// <summary>
    /// 获取正在运行的实例
    /// </summary>
    public async Task<List<PipelineInstance>> GetRunningInstancesAsync()
    {
        return await _dbProvider.Orm.Select<PipelineInstance>()
            .Where(i => i.Status == TaskStatus.Running)
            .ToListAsync();
    }

    /// <summary>
    /// 获取流水线的历史实例
    /// </summary>
    public async Task<List<PipelineInstance>> GetPipelineHistoryAsync(long pipelineId, int limit = 10)
    {
        return await _dbProvider.Orm.Select<PipelineInstance>()
            .Where(i => i.PipelineId == pipelineId)
            .OrderByDescending(i => i.CreatedAt)
            .Take(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 获取实例的任务列表
    /// </summary>
    public async Task<List<TaskEntity>> GetInstanceTasksAsync(long instanceId)
    {
        return await _dbProvider.Orm.Select<TaskEntity>()
            .Where(t => t.PipelineInstanceId == instanceId)
            .Include(t => t.Node)
            .ToListAsync();
    }

    /// <summary>
    /// 获取实例的统计信息
    /// </summary>
    public async Task<InstanceStatistics> GetInstanceStatisticsAsync(long instanceId)
    {
        var tasks = await GetInstanceTasksAsync(instanceId);

        return new InstanceStatistics
        {
            TotalTasks = tasks.Count,
            PendingTasks = tasks.Count(t => t.Status == TaskStatus.Pending),
            RunningTasks = tasks.Count(t => t.Status == TaskStatus.Running),
            SuccessTasks = tasks.Count(t => t.Status == TaskStatus.Success),
            FailedTasks = tasks.Count(t => t.Status == TaskStatus.Failed),
            CancelledTasks = tasks.Count(t => t.Status == TaskStatus.Cancelled)
        };
    }

    /// <summary>
    /// 清理旧实例（保留最近N个）
    /// </summary>
    public async Task CleanupOldInstancesAsync(long pipelineId, int keepCount = 50)
    {
        // 获取需要删除的实例ID
        var instancesToDelete = _dbProvider.Orm.Select<PipelineInstance>()
            .Where(i => i.PipelineId == pipelineId)
            .OrderByDescending(i => i.CreatedAt)
            .Skip(keepCount)
            .ToList(i => i.Id);

        if (instancesToDelete.Count > 0)
        {
            try
            {
                foreach (var instanceId in instancesToDelete)
                {
                    // 删除任务
                    await _dbProvider.Orm.Delete<TaskEntity>()
                        .Where(t => t.PipelineInstanceId == instanceId)
                        .ExecuteAffrowsAsync();
                }

                // 删除实例
                await _dbProvider.Orm.Delete<PipelineInstance>()
                    .Where(i => instancesToDelete.Contains(i.Id))
                    .ExecuteAffrowsAsync();

                _logger.LogInformation("清理旧实例: PipelineId={PipelineId}, 删除数量={Count}",
                    pipelineId, instancesToDelete.Count);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理旧实例失败: PipelineId={PipelineId}", pipelineId);
                throw;
            }
        }
    }
}

/// <summary>
/// 实例统计信息
/// </summary>
public class InstanceStatistics
{
    public int TotalTasks { get; set; }
    public int PendingTasks { get; set; }
    public int RunningTasks { get; set; }
    public int SuccessTasks { get; set; }
    public int FailedTasks { get; set; }
    public int CancelledTasks { get; set; }
}
